local desc = [[
# 骗子牌玩法简介

一款充满欺骗与心理博弈的卡牌游戏，玩家需要巧妙运用谎言和策略存活到最后。

## 游戏流程

1. 游戏使用20张牌：6张Q、6张K、6张A、2张大小王（万能牌）
2. 每轮随机指定一张主牌（如Q）
3. 玩家轮流进行回合：
   * 出1-3张牌并声明牌面（如"2张Q"）
   * 可以撒谎（实际出的牌与声明不符）
4. 下一玩家选择：
   * 质疑：检查上家是否撒谎
     - 若撒谎，上家进行俄罗斯轮盘（至多有6次机会）
     - 若未撒谎，由质疑者进行受罚

     结束当前轮次

     重新分发手牌和指定主牌
   * 继续：出牌并声明相同牌面
5. 胜利条件：存活至最后一名玩家

## 特别说明
万能牌（大小王）可作为任何牌使用。
]]

-- 俄罗斯轮盘惩罚
---@param room Room
---@param player ServerPlayer
---@param num integer?
local function russianRoulette(room, player, num)
  room:removePlayerMark(player,"@[bullets]",1)
  room:delay(200)
  local bullet = math.random(1, num > 0 and num or 6)
  if bullet == 1 then
    room:broadcastPlaySound("./packages/water_wegame/audio/effect/revolver2")
    room:delay(500)
    room:sendLog{
        type = "#CheatRouletteDeath",
        to = {player.id},
        toast = true,
    }
    room:killPlayer{
      who = player
    }
    room:setPlayerProperty(player, "dead", true)
    return true
  else
    room:broadcastPlaySound("./packages/water_wegame/audio/effect/revolver1")
    room:delay(500)
    room:sendLog{
        type = "#CheatRouletteSurvive",
        to = {player.id},
        toast = true,
    }
    return false
  end
end

-- 检查出牌是否撒谎
---@param cards number[] 牌ID列表
---@param trump number 主牌点数
local function checkCheat(cards, trump)
    for _, id in ipairs(cards) do
        local card = Fk:getCardById(id)
        -- 万能牌(大小王)或主牌都算有效
        if card.name ~= "Joker_poker" and card.number ~= trump then
            return true  -- 发现撒谎
        end
    end
    return false  -- 未撒谎
end

-- 主游戏逻辑
---@param room Room
local function cheatGame(room)
    -- 洗牌发牌
    room:cleanProcessingArea()
    room:shuffleDrawPile()
    for _, p in ipairs(room.alive_players) do
        p:drawCards(5)
    end
    -- 随机主牌 (Q=12, K=13, A=1)
    local trumps = {12, 13, 1}
    local trump = table.random(trumps)
    local trumpName = ({[12]="Q", [13]="K", [1]="A"})[trump]
    room:setTag("CheatTrump", trump)
    room:sendLog{
      type = "#trumpNameCard",
      arg = trumpName,
      toast = true,
    }
    room:setBanner("@cheat_card",trumpName)
    local roundCount = room:getTag("RoundCount") or 0
    roundCount = roundCount + 1
    room:setTag("RoundCount",  roundCount)
    room:doBroadcastNotify("UpdateRoundNum", roundCount)
    --room:doBroadcastNotify("UpdateTrump", trumpName)
    -- 随机起始玩家
    local current = table.random(room.alive_players)
    local processingCards = {}  -- 处理区牌
    for _, p in ipairs(room.alive_players) do
      room:setPlayerMark(p,"@[bullets]",6)
      room:broadcastPlaySound("./packages/water_wegame/audio/effect/revolver0")
    end
    room:delay(3000)
    while #room.alive_players > 1 do
        -- 检查玩家是否有牌
        if table.every(room.alive_players,function (cp)
            return cp:getHandcardNum() == 0
        end) then
          -- 洗牌发牌
          room:cleanProcessingArea()
          room:shuffleDrawPile()
          for _, p in ipairs(room.alive_players) do
              p:drawCards(5)
          end
          -- 随机主牌 (Q=12, K=13, A=1)
          trumps = {12, 13, 1}
          trump = table.random(trumps)
          trumpName = ({[12]="Q", [13]="K", [1]="A"})[trump]
          room:setTag("CheatTrump", trump)
          room:sendLog{
            type = "#trumpNameCard",
            arg = trumpName,
            toast = true,
          }
          room:setBanner("@cheat_card",trumpName)
          roundCount = roundCount + 1
          room:setTag("RoundCount",  roundCount)
          room:doBroadcastNotify("UpdateRoundNum", roundCount)
        end
        if current:getHandcardNum() > 0 then
          -- 当前玩家出牌
          local maxCards = math.min(3, #current.player_cards[Player.Hand])
          local cards = room:askToCards(current,{
            max_num = maxCards,
            min_num = 1,
            include_equip = false,
            skill_name = "CheatPlay",
            cancelable = false,
            pattern = ".",
            prompt = "#cheat-play:::"..trumpName
          })
          room:broadcastPlaySound("./packages/water_wegame/audio/effect/poker")
          -- 记录出牌
          local lastPlayer = current
          local lastCards = cards
          -- 移动到处理区
          room:moveCardTo(cards, Card.Processing, nil, fk.ReasonJustMove, nil, nil, false)
          for _, id in ipairs(cards) do
              table.insert(processingCards, id)
          end
          room:sendLog{
              type = "#CheatPlayCard",
              from = current.id,
              arg = #cards,
              arg2 = trumpName,
              card = cards,
          }
          -- 下一玩家选择
          local nextPlayer = room:getPlayerById(current:getNextAlive().id)
          if table.every(room.alive_players,function (cp)
            return cp:getHandcardNum() == 0
          end) then
            -- 洗牌发牌
              room:cleanProcessingArea()
              room:shuffleDrawPile()
              for _, p in ipairs(room.alive_players) do
                  p:drawCards(5)
              end
              -- 随机主牌 (Q=12, K=13, A=1)
              trumps = {12, 13, 1}
              trump = table.random(trumps)
              trumpName = ({[12]="Q", [13]="K", [1]="A"})[trump]
              room:setTag("CheatTrump", trump)
              room:sendLog{
                type = "#trumpNameCard",
                arg = trumpName,
                toast = true,
              }
              room:setBanner("@cheat_card",trumpName)
              roundCount = roundCount + 1
              room:setTag("RoundCount",  roundCount)
              room:doBroadcastNotify("UpdateRoundNum", roundCount)
              current = nextPlayer
          else
            while nextPlayer:getHandcardNum() == 0 do
              nextPlayer = room:getPlayerById(nextPlayer:getNextAlive().id)
            end
            local choices = {"doubt"}
            if lastPlayer:getHandcardNum() > 0 then
              table.insert(choices,"pass")
            end
            local choice = room:askToChoice(nextPlayer,{
              choices = choices,
              all_choices = {"doubt", "pass"},
              prompt = "#cheat-choose:::"..lastPlayer._splayer:getScreenName(),
              skill_name = "DoubtPlay",
            })
            if choice == "doubt" then
                -- 检查是否撒谎
                room:broadcastPlaySound("./packages/water_wegame/audio/effect/table")
                local isCheating = checkCheat(lastCards, trump)
                current:showCards(lastCards)
                if isCheating then
                    room:sendLog{
                        type = "#CheatCaught",
                        from = nextPlayer.id,
                        to = {lastPlayer.id},
                        toast = true,
                    }
                    -- 上家受罚
                    russianRoulette(room, lastPlayer, lastPlayer:getMark("@[bullets]"))
                else
                    room:sendLog{
                        type = "#CheatWrongAccusation",
                        from = nextPlayer.id,
                        to = {lastPlayer.id},
                        toast = true,
                    }
                    -- 质疑者受罚
                    russianRoulette(room, nextPlayer, nextPlayer:getMark("@[bullets]"))
                end
                if #room.alive_players == 1 then break end
                -- 弃置处理区所有牌
                room:moveCardTo(table.filter(cards, function(id) return room:getCardArea(id) == Card.Processing end) or room.processing_area, Card.DrawPile, nil, fk.ReasonJustMove, nil, nil, false)
                room:moveCardTo(processingCards, Card.DrawPile, nil, fk.ReasonJustMove, nil, nil, false)
                processingCards = {}
                -- 新回合开始
                for _, p in ipairs(room.players) do
                  if #p:getCardIds("h") then
                    room:moveCardTo(p:getCardIds("h"), Card.DrawPile, nil, fk.ReasonJustMove, nil, nil, false)
                  end
                end
                -- 洗牌发牌
                room:shuffleDrawPile()
                for _, p in ipairs(room.alive_players) do
                    p:drawCards(5)
                end
                -- 随机主牌 (Q=12, K=13, A=1)
                trumps = {12, 13, 1}
                trump = table.random(trumps)
                trumpName = ({[12]="Q", [13]="K", [1]="A"})[trump]
                room:setTag("CheatTrump", trump)
                room:sendLog{
                  type = "#trumpNameCard",
                  arg = trumpName,
                  toast = true,
                }
                room:setBanner("@cheat_card",trumpName)
                roundCount = roundCount + 1
                room:setTag("RoundCount",  roundCount)
                room:doBroadcastNotify("UpdateRoundNum", roundCount)

                current = room:getPlayerById(current:getNextAlive().id)
            else
                -- 继续游戏
                current = nextPlayer
            end
          end
        end
    end
    -- 游戏结束
    if #room.alive_players == 1 then
        --room:setPlayerProperty(room.alive_players[1], "role", "lord")
        room:sendLog{
            type = "#CheatGameOver",
            arg = room.alive_players[1]._splayer:getScreenName(),
            toast = true,
        }
        room:gameOver(room.alive_players[1].role)
    end
end
-- 游戏逻辑
local function logic()
    ---@class CheatLogic: GameLogic
    local cheatLogic = GameLogic:subclass("CheatLogic")
    function cheatLogic:chooseGenerals()
        local room = self.room
        for _, p in ipairs(room.players) do
            local avatar = p._splayer:getAvatar()
            if avatar == "anjiang" then 
                avatar = table.random{"blank_shibing", "blank_nvshibing"}
            end
            local general = Fk.generals[avatar] or Fk.generals["sunquan"]
            room:setPlayerProperty(p, "general", general.name)
            room:setPlayerProperty(p, "kingdom", general.kingdom)
            room:setPlayerProperty(p, "role", p._splayer:getScreenName())
            room:setPlayerProperty(p, "role_shown", true)
        end
    end
    function cheatLogic:broadcastGeneral() end
    function cheatLogic:attachSkillToPlayers() end
    function cheatLogic:prepareForStart() end
    function cheatLogic:action()
        cheatGame(self.room)
    end
    return cheatLogic
end

-- 创建游戏模式
local mode = fk.CreateGameMode {
    name = "cheat_game",
    minPlayer = 2,
    maxPlayer = 4,
    logic = logic,
    whitelist = {
      "water_wegame_cheat_mode"
    }
}

Fk:addQmlMark{
  name = "bullets",
  how_to_show = function (name, value, player)
    return (6-value).."/6"
  end,
  qml_path = "",
}

-- 加载翻译
Fk:loadTranslationTable {
  ["cheat_game"] = "骗子牌",
  [":cheat_game"] = desc,
  -- 日志翻译
  ["#trumpNameCard"] = "本轮需要打出 %arg点牌",
  ["#CheatPlayCard"] = "%from 出了 %arg 张 %arg2",
  ["#CheatCaught"] = "%from 抓住了 %to 的谎言！",
  ["#CheatWrongAccusation"] = "%from 错误地质疑了 %to！",
  ["#CheatRouletteDeath"] = "%to 不幸中弹身亡！",
  ["#CheatRouletteSurvive"] = "%to 幸运地躲过了子弹！",
  ["#CheatNoCards"] = "%to 没有手牌，跳过回合",
  ["#CheatGameOver"] = "游戏结束！%arg 获得了胜利！",
  -- 提示信息
  ["#cheat-play"] = "请出1-3张牌并声明为 %arg",
  ["#cheat-choose"] = "请选择：质疑 %arg 还是继续出牌？",
  ["#cheat-ask"] = "请选择行动",
  ["doubt"] = "质疑",
  ["pass"] = "继续",
  ["CheatPlay"] = "出牌",
  ["DoubtPlay"] = "质疑",
  ["@[bullets]"] = "左轮",
  ["@cheat_card"] = "本轮主牌",
}

return mode